package org.iabako.client.ui.page.business.expense;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.TableCellElement;
import com.google.gwt.dom.client.TableElement;
import com.google.gwt.dom.client.TableRowElement;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.datepicker.client.CalendarUtil;
import org.iabako.client.config.page.PageConfigSearchEnum;
import org.iabako.client.config.page.PageEnum;
import org.iabako.client.navigation.NavigationController;
import org.iabako.client.tools.DefaultSuggestHandler;
import org.iabako.client.tools.IabakoAsyncCallback;
import org.iabako.client.ui.form.business.expense.ExpenseSearchForm;
import org.iabako.client.ui.layout.field.Button;
import org.iabako.client.ui.layout.widget.datatable.DataTable;
import org.iabako.client.ui.page.AbstractSearchPage;
import org.iabako.client.user.AuthenticateUserProvider;
import org.iabako.shared.entity.enumeration.NotificationType;
import org.iabako.shared.entity.enumeration.TrackingType;
import org.iabako.shared.iservice.business.ExpenseServiceAsync;
import org.iabako.shared.iservice.generic.CRUDServiceAsync;
import org.iabako.shared.iservice.generic.SearchServiceAsync;
import org.iabako.shared.iservice.generic.SuggestServiceAsync;
import org.iabako.shared.querydefinition.columndefinition.ExpenseColumnEnum;
import org.iabako.shared.querydefinition.dto.QueryDefinitionDTO;
import org.iabako.shared.querydefinition.dto.QueryOperatorEnum;
import org.iabako.shared.tools.GenericTools;

import java.util.Date;

/**
 * Created by jose on 04/11/14.
 */
public class ExpenseSearch extends AbstractSearchPage {

    interface MyUiBinder extends UiBinder<HTMLPanel, ExpenseSearch> {
    }

    private static final MyUiBinder binder = GWT.create(MyUiBinder.class);

    @UiField
    HTMLPanel resultsPanel;
    @UiField
    HTMLPanel expenseSearchPanel;
    @UiField
    TableElement totalTable;

    public ExpenseSearchForm expenseSearchForm;

    public ExpenseSearch() {
        super(false);

        Button createExpense = new Button("pageactionbutton", "expense_make_title");
        page.actionButtons.add(createExpense);

        createExpense.getButton().addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                NavigationController.getInstance().goTo(PageEnum.ExpenseMake);
            }
        });
    }

    @Override
    protected DataTable getCustomDataTable() {
        DataTable dataTable = new DataTable(getSearchServiceAsync(), getCRUDServiceAsync(),
                getQueryDefinitionDTO(), getModificationPage(), getSearchPageConfigEnum()) {

            @Override
            protected void customTaskAfterRender() {
                totalTable.setInnerHTML("");

                if (queryDefinitionDTO.getCountTotal() == 0) {
                    return;
                }

                ExpenseServiceAsync.Util.getInstance().getTotal(queryDefinitionDTO, new IabakoAsyncCallback<Double>() {
                    public void onSuccess(Double total) {
                        addTotalTable(total);
                        super.onSuccess(total);
                    }
                });
            }

            private void addTotalTable(Double total) {
                totalTable.setClassName(dataTable.getClassName() + " resultstabletotal");
                resultsContainer.insertAfter(totalTable, dataTable);

                TableRowElement totalRow = totalTable.insertRow(0);

                TableRowElement referenceRow = dataTable.getRows().getItem(0);
                int indexOfExpenseValue = queryDefinitionDTO.getSelectColumns().indexOf(ExpenseColumnEnum.paymentValue);

                for (int i = 0; i < referenceRow.getCells().getLength(); i++) {
                    boolean totalLabel = i == indexOfExpenseValue - 1;
                    boolean totalValue = i == indexOfExpenseValue;

                    String className = referenceRow.getCells().getItem(i).getClassName();

                    if (totalLabel) {
                        TableCellElement cell = totalRow.insertCell(i);
                        cell.setInnerHTML("Total <span>(" + queryDefinitionDTO.getCountTotal() + " resultados)<span> : ");
                        cell.setClassName(className + " resultstabletotallabel");
                    } else if (totalValue) {
                        TableCellElement valueCell = totalRow.insertCell(i);
                        valueCell.setInnerText(GenericTools.formatAmount(total + ""));
                        valueCell.setClassName(className + " resultstabletotalvalue");
                    } else {
                        TableCellElement cell = totalRow.insertCell(i);
                        cell.setClassName(className);
                    }
                }
            }
        };

        return dataTable;
    }

    @Override
    protected void dataTableRemoveCustomAction() {
        AuthenticateUserProvider.getNotificationPanel().refresh(NotificationType.newPastExpenses, NotificationType.futureExpenses);
        AuthenticateUserProvider.getTrackingPanel().refresh(TrackingType.expenseDelete);
    }

    @Override
    protected SearchServiceAsync getSearchServiceAsync() {
        return ExpenseServiceAsync.Util.getInstance();
    }

    @Override
    protected CRUDServiceAsync getCRUDServiceAsync() {
        return ExpenseServiceAsync.Util.getInstance();
    }

    @Override
    protected SuggestServiceAsync getSuggestServiceAsync() {
        return ExpenseServiceAsync.Util.getInstance();
    }

    @Override
    protected HTMLPanel getResultsPanel() {
        return resultsPanel;
    }

    @Override
    protected HTMLPanel getSearchPanel() {
        return expenseSearchPanel;
    }

    @Override
    protected HTMLPanel getContentPanel() {
        return binder.createAndBindUi(this);
    }

    @Override
    protected Composite getSearchForm(DataTable dataTable) {
        if (expenseSearchForm == null) {
            expenseSearchForm = new ExpenseSearchForm(new DefaultSuggestHandler(getSuggestServiceAsync()), dataTable);
        }
        return expenseSearchForm;
    }

    @Override
    protected PageConfigSearchEnum getSearchPageConfigEnum() {
        return PageConfigSearchEnum.ExpenseSearch;
    }

    @Override
    protected PageEnum getModificationPage() {
        return PageEnum.ExpenseModify;
    }

    @Override
    protected QueryDefinitionDTO getQueryDefinitionDTO() {
        QueryDefinitionDTO queryDefinitionDTO = new QueryDefinitionDTO();
        queryDefinitionDTO.setAscByDefault(false);
        queryDefinitionDTO.setAsc(false);

        Date oneMonthInFuture = new Date();
        CalendarUtil.addMonthsToDate(oneMonthInFuture, 1);
        queryDefinitionDTO.addCriteria(ExpenseColumnEnum.paymentDate, QueryOperatorEnum.LESS_THAN_OR_EQUALS, oneMonthInFuture);

        return queryDefinitionDTO;
    }
}
